from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema

from utils.base_views import MultipleDestroyMixin
from ..models import RoleModel, PermissionsModel
from ..serializers import BaseRolesSerializer, RolesPartialSerializer, RoleSetPermissionsSerializer


# 角色数据库中有一个固定的角色： admin, 这个角色代表所有权限， 它不能删除
class RolesView(viewsets.ModelViewSet, MultipleDestroyMixin):
    """
    create:
    权限--新增
    status： 201（成功）， return：新增权限信息

    destroy：
    权限--删除 单个角色
    status： 204（成功）， return：None

    multiple_destroy：
    权限--批量删除 多个角色，传入id的列表
    status： 204（成功）， return：None

    update：
    角色--修改  只是修改角色名字
    status： 200（成功）， return：修改后的角色信息

    partial_update：
    角色--局部修改（角色批量修改授权）， 只能针对某一个角色一次性授权，之前的授权会被覆盖
    status： 200（成功）， return：修改增权限信息

    list:
    角色--获取列表

    set_permission_to_role:
    给单个角色单一授权， 一次只能授予该角色一个permission， 也可以取消一个permission
    status：200（成功）， return：修改后的角色信息
    """
    queryset = RoleModel.objects.all()

    # permission_classes = [IsAuthenticated]

    def get_serializer_class(self):
        if self.action == "partial_update":
            return RolesPartialSerializer
        elif self.action == "set_permission_to_role":
            return RoleSetPermissionsSerializer
        else:
            return BaseRolesSerializer

    @action(methods=["post"], detail=False)
    def set_permission_to_role(self, request, *args, **kwargs):
        ser = RoleSetPermissionsSerializer(data=request.data)
        if ser.is_valid():  # 参数验证通过了
            # 查询当前角色
            role = RoleModel.objects.get(id=ser.validated_data.get('role_id'))  # 查询当前角色
            # 查询当前权限
            permission = PermissionsModel.objects.get(id=ser.validated_data.get('permission_id'))  # 查询当前权限
            # 把当前的权限授予当前角色
            if ser.validated_data.get('is_create'):
                role.permissions.add(permission)
            else:  # 取消授权
                role.permissions.remove(permission)

            result_serializer = BaseRolesSerializer(instance=role)
            return Response(data=result_serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(data=ser.errors, status=status.HTTP_400_BAD_REQUEST)

    # 重写父类的删除函数， 因为admin角色不能删除
    def destroy(self, request, *args, **kwargs):
        if self.get_object().name == "admin":
            return Response(data={"detail": "admin角色不能删除"}, status=status.HTTP_400_BAD_REQUEST)
        return super().destroy(request, *args, **kwargs)

    del_ids = openapi.Schema(type=openapi.TYPE_OBJECT, required=['ids'], properties={
        "ids": openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_INTEGER),
                              description="选择那些需要删除的ID（主键）列表")
    })

    # action装饰器可以接受2个参数
    # methods： 声明该actions对应的请求方法， 列表传递
    # detail： 声明该action的路径是否与单一资源对应， 及是否是xxx/<pk>/action方法名/
    #   True： 表示路径格式是xxx/<pk>/action方法名
    #   False： 表示路径格式是xxx/action方法名/
    @swagger_auto_schema(method="delete", request_body=del_ids, operation_description="删除")
    @action(methods=['delete'], detail=False)
    def multiple_delete(self, request, *args, **kwargs):
        delete_ids = request.data.get('ids')
        try:
            admin = RoleModel.objects.get(name='admin')
            if isinstance(delete_ids, list):
                if admin.id in delete_ids:
                    return Response(data={"detail": "admin角色不能删除"}, status=status.HTTP_400_BAD_REQUEST)
        except RoleModel.DoesNotExist as e:
            pass
        return super().multiple_delete(request, *args, **kwargs)
